﻿using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using OpenTK.Graphics.OpenGL4;

namespace Painter3D.RenderSys
{
    /// <summary>
    /// 材质对象
    /// <para>Texture0 用于默认贴图，工作使用材质从Texture1开始</para>
    /// </summary>
    public class Texture : IDisposable
    {
        readonly private int Handle;
        /// <summary>
        /// 创建纹理材质 [png rgba]
        /// </summary>
        /// <param name="path">图像文件路径</param>
        public Texture(string path)
        {
            using (Bitmap bmp = new Bitmap(path))
            {
                bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);
                Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
                BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, bmp.PixelFormat);

                IntPtr ptr = bmpData.Scan0;
                int bytes = bmpData.Stride * bmp.Height;
                byte[] texture = new byte[bytes];
                Marshal.Copy(ptr, texture, 0, bytes);
                bmp.UnlockBits(bmpData);
                /*
                byte[] data = new byte[texture.Length / 4];
                for (int i = 0; i < texture.Length / 4; i++)
                {
                    data[i] = texture[i * 4 + 3];
                }*/

                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);

                Handle = GL.GenTexture();
                GL.ActiveTexture(TextureUnit.Texture0);
                GL.BindTexture(TextureTarget.Texture2D, Handle);
                GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bmp.Width, bmp.Height, 0, OpenTK.Graphics.OpenGL4.PixelFormat.Bgra, PixelType.UnsignedByte, texture);
                //GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Alpha, bmp.Width, bmp.Height, 0, OpenTK.Graphics.OpenGL4.PixelFormat.Alpha, PixelType.UnsignedByte, data);
                GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);
            }
        }
        /// <summary>
        /// 将对应材质绑定到纹理单元
        /// </summary>
        /// <param name="textureUnit"></param>
        public void Use(int textureUnit = 0)
        {
            GL.ActiveTexture(TextureUnit.Texture0 + textureUnit);
            GL.BindTexture(TextureTarget.Texture2D, Handle);
        }



        #region Dispose
        public void Dispose()
        {
            GL.DeleteTexture(Handle);
            GC.SuppressFinalize(this);
        }

        ~Texture()
        {
            GL.DeleteTexture(Handle);
        }
        #endregion
    }
}
